{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "import numpy as np\n",
    "from openai import OpenAI\n",
    "import colorsys  # Import for color calculations\n",
    "from IPython.display import display, HTML\n",
    "from openai.resources.chat.completions import ChatCompletion\n",
    "\n",
    "client = OpenAI()\n",
    "\n",
    "system_prompt = \"\"\"You are Jeff Dean. We need to compare two git patches to determine whether they are functionally equivalent or different. Ignore changes such as logs or comments. Ignore implementation differences if the resulting behavior is the same.\\n\\nBe exceptionally meticulous to determine whether or not they perform the same functional.\\n\\nRespond in the following format:\\n\\n<summary_of_patch_one>\\nsummarize the first patch's functional changes\\n</summary_of_patch_one>\\n\\n<summary_of_patch_two>\\nsummarize the second patch's functional changes\\n</summary_of_patch_two>\\n\\n<equivalent_or_different>\\nwhether the patches are functionally equivalent or different. answer in one word.\\n</equivalent_or_different>\"\"\"\n",
    "\n",
    "example_prompt = \"\"\"<patch_one>\n",
    "--- \n",
    "+++ \n",
    "@@ -516,17 +516,21 @@\n",
    "     def __eq__(self, other):\n",
    "         # Needed for @total_ordering\n",
    "         if isinstance(other, Field):\n",
    "+            if hasattr(self, 'model') and hasattr(other, 'model') and self.model != other.model:\n",
    "+                return False\n",
    "             return self.creation_counter == other.creation_counter\n",
    "         return NotImplemented\n",
    "\n",
    "     def __lt__(self, other):\n",
    "         # This is needed because bisect does not take a comparison function.\n",
    "         if isinstance(other, Field):\n",
    "+            if hasattr(self, 'model') and hasattr(other, 'model') and self.model != other.model:\n",
    "+                return self.model._meta.label < other.model._meta.label\n",
    "             return self.creation_counter < other.creation_counter\n",
    "         return NotImplemented\n",
    "\n",
    "     def __hash__(self):\n",
    "-        return hash(self.creation_counter)\n",
    "+        return hash((self.model._meta.label, self.creation_counter)) if hasattr(self, 'model') else hash(self.creation_counter)\n",
    "\n",
    "     def __deepcopy__(self, memodict):\n",
    "         # We don't have to deepcopy very much here, since most things are not\n",
    "</patch_one>\n",
    "\n",
    "<patch_two>\n",
    "--- \n",
    "+++ \n",
    "@@ -516,17 +516,21 @@\n",
    "     def __eq__(self, other):\n",
    "         # Needed for @total_ordering\n",
    "         if isinstance(other, Field):\n",
    "+            if hasattr(self, 'model') and hasattr(other, 'model') and self.model != other.model:\n",
    "+                return False\n",
    "             return self.creation_counter == other.creation_counter\n",
    "         return NotImplemented\n",
    "\n",
    "     def __lt__(self, other):\n",
    "         # This is needed because bisect does not take a comparison function.\n",
    "         if isinstance(other, Field):\n",
    "+            if hasattr(self, 'model') and hasattr(other, 'model') and self.model != other.model:\n",
    "+                return self.model._meta.label < other.model._meta.label\n",
    "             return self.creation_counter < other.creation_counter\n",
    "         return NotImplemented\n",
    "\n",
    "     def __hash__(self):\n",
    "-        return hash(self.creation_counter)\n",
    "+        return hash((self.model._meta.label, self.creation_counter)) if hasattr(self, 'model') else hash(self.creation_counter)\n",
    "\n",
    "     def __deepcopy__(self, memodict):\n",
    "         # We don't have to deepcopy very much here, since most things are not\n",
    "</patch_two>\"\"\"\n",
    "\n",
    "# parse diff_comparison.csv using csvreader to get equivalent_patch, non_equivalent_patch, and patch_to_compare\n",
    "def parse_diff_comparison():\n",
    "    equivalent_patch = []\n",
    "    non_equivalent_patch = []\n",
    "    patch_to_compare = []\n",
    "    with open('tests/diff_comparison.csv', 'r') as file:\n",
    "        for line in file.readlines()[1:]:\n",
    "            line = line.split('<diff>')\n",
    "            equivalent_patch.append(line[0])\n",
    "            non_equivalent_patch.append(line[1])\n",
    "            patch_to_compare.append(line[2])\n",
    "    return equivalent_patch, non_equivalent_patch, patch_to_compare\n",
    "\n",
    "\n",
    "def generate_call_from_patches(patch_one, patch_two):\n",
    "    response = client.chat.completions.create(\n",
    "        model=\"gpt-4-turbo-preview\",\n",
    "        messages=[\n",
    "            {\n",
    "            \"role\": \"system\",\n",
    "            \"content\": system_prompt\n",
    "            },\n",
    "            {\n",
    "            \"role\": \"user\",\n",
    "            # \"content\": f\"<patch_one>{patch_one}</patch_one>\\n\\n<patch_two>{patch_two}</patch_two>\"\n",
    "            \"content\": example_prompt\n",
    "            },\n",
    "        ],\n",
    "        temperature=0.2,\n",
    "        max_tokens=512,\n",
    "        top_p=1,\n",
    "        frequency_penalty=0,\n",
    "        presence_penalty=0,\n",
    "        logprobs=True,\n",
    "        top_logprobs=2,\n",
    "    )\n",
    "    acc = {np.round(np.exp(logprob.logprob)*100,2): logprob.token for logprob in response.choices[0].logprobs.content[0].top_logprobs}\n",
    "    logprobs = response.choices[0].logprobs.content[0].top_logprobs\n",
    "    response_content = response.choices[0].message.content\n",
    "    \n",
    "    # regex match xml tags of equivalent_or_different\n",
    "    match = re.search(r'<equivalent_or_different>(.*?)</equivalent_or_different>', response_content, re.DOTALL)\n",
    "    equivalent_or_different = match.group(1) if match else None\n",
    "    return equivalent_or_different, response\n",
    "\n",
    "equivalent_or_different, response = generate_call_from_patches(example_prompt, example_prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.9999998063873687, 0.9999998063873687, 1.0, 1.0, 1.0, 0.9999801379802525, 0.8479024628751181, 0.3911284720293332, 0.9999928926002577, 0.3665643108724679, 0.2500120655711193, 0.7668703171051177, 0.44927909137019323, 0.5709381807918824, 0.731163206095178, 0.9283719075812265, 0.409517127977843, 0.90578843650422, 0.9415850927407695, 0.6223789919383691, 0.9623325268861276, 0.7373533632713033, 0.37568580872734114, 0.8007521864451503, 0.9955315891874188, 0.6583999536613336, 0.47502834644583847, 0.8031175316938742, 0.7956882544396348, 0.4019135352260091, 0.7494857307347274, 0.9999983759447189, 0.999999687183719, 0.9999860980626328, 0.9996990219729768, 0.9104110574305577, 0.999979303571174, 1.0, 0.9999998063873687, 1.0, 0.9999947998470209, 0.980736856951861, 0.9772183750492627, 0.6325488678133417, 0.983620407590506, 0.8303222753498575, 0.673351949409038, 0.5177427405261549, 0.9950334920880923, 0.9572050759952068, 0.8409635089684246, 0.9731509890065737, 0.9595187617996692, 0.6633786537694937, 1.0, 0.999972151525776, 0.9998165026676954, 0.6148528795729021, 0.7719970270008072, 0.2958863651166834, 0.836106944530063, 0.9935026506518648, 0.2082120182340838, 0.2673714470321935, 0.7383006149428899, 0.529264855709362, 0.4866631397807406, 0.6164880501126919, 0.9386651745373311, 0.6624948597631071, 0.9973120402505037, 0.8820234464958924, 0.7427261169899146, 0.9864345059921331, 0.9999837140256179, 0.9999998063873687, 1.0, 0.9999989719621285, 0.9019182274122527, 0.9260378642992145, 0.8753491882035838, 0.9378691581038419, 0.9996773410256069, 1.0, 0.9999998063873687, 1.0, 0.9999981375378344, 0.701839677969218, 0.9089185525265472, 0.8207963429876175, 0.7194775322758727, 0.9999973031140367, 0.9715868794604537, 0.2600464006112426, 0.48313667226729107, 0.9792123891361896, 0.6343656029153912, 0.9999995679800934, 0.9134637924679638, 0.7796580444321872, 1.0, 1.0, 1.0, 0.999996945503965, 0.9985895715903989, 0.9761965867510648, 0.8706452635521588, 0.9998622621767251, 0.7510858421163839, 0.9825871803447088, 0.9973237659165537, 0.9949661062242202, 0.9935649015041184, 0.9999408023272515, 0.9912133165315844, 0.9995210634667342, 0.9988704250506137, 0.8547947904690257, 0.9998894299073234, 0.6035632431398037, 1.0, 0.9999992103693118, 0.99999861435166, 0.6150867894963457, 0.9997445341369622, 0.4526111548187091, 0.6970871222349776, 0.9382315832405463, 0.9988111963875416, 0.5120695619436514, 0.9999992103693118, 0.9984501540535947, 0.86368320352677, 0.9885419986703728, 0.9532677708851793, 0.5926643265722311, 0.3528554133022539, 0.9953574720032382, 1.0, 0.9999983759447189, 0.9999994487765019, 1.0, 1.0, 0.999987886094374, 1.0, 1.0, 1.0, 0.9999998063873687, 1.0, 0.9999927733971121, 0.9994749841690692, 0.9993941309128428, 0.9999926541946806, 0.796659968898825, 0.9962752890091361, 0.9969604854062093, 0.998751022422549, 0.9999962302846055, 0.5916736872715844, 0.4913824174795946, 0.5413924430843089, 0.9988653088493992, 0.98653228819934, 0.3293656984780839, 0.9376252219286785, 0.9772304339984144, 0.47900925991211935, 0.9755763621231133, 0.9999038520625093, 0.8622759085574196, 0.9794157858162287, 0.62239295827965, 0.9998938399653754, 0.999970244320709, 0.9651227535324554, 0.9255157771039008, 0.35731143876842486, 0.6401593431150124, 0.8996800624722029, 0.38349747587835253, 0.599603587269846, 0.9005204995450254, 0.6450140367629399, 0.7057828265005106, 0.958897308201275, 0.9999502188991202, 0.7590462864354547, 0.9955691632497136, 0.999998733555102, 0.9999936078174302, 0.9957564713210002, 0.9895302761348279, 0.8162387998139012, 0.6403809598203274, 0.9398192287992667, 1.0, 0.9999980183344636, 1.0, 0.9999976607241362, 0.9999715555225519, 0.9999574899895761, 1.0, 1.0, 0.9999995679800934, 0.9999870516788303, 0.9910627091462713, 0.48555774941156826, 0.308609640522359, 0.6915126323525524, 0.8523985754342325, 0.9016266483147343, 0.8790649704310227, 0.9959283644770008, 0.6405137245538873, 0.39362230350516436, 0.7033566922512478, 0.56453155383087, 0.6763104248399067, 0.918313194562223, 0.9797245267355279, 0.37500620743077306, 0.77880522224852, 0.999999687183719, 0.9999253068846697, 0.999999687183719, 0.9999859788602972, 0.9932251511698491, 0.8835081487545569, 0.77258566743716, 0.5046469313826962, 0.8269629545033866, 0.5381297644722931, 0.6805774976365756, 0.9990544514130583, 0.9624917348749276, 0.9992145059920637, 0.9999927733971121, 0.9973782039264097, 0.999858090640086, 0.9999684563215123, 0.9991258425983903, 0.6001800172593721, 0.9999855020530963, 0.919636748035847, 0.8837913929660335, 0.9947985500331892, 0.8219226402275929, 1.0, 0.9999964686909352, 0.9975767463310525, 0.5389781213954727, 0.7826711800853157, 0.5875839556144364, 0.46762659755648217, 0.9503489443378271, 0.8293355508004471, 0.9447165939968367, 0.9999988527586582, 0.9997409589369315, 0.8069446503429544, 0.9992608042398954, 0.9999978991308068, 0.9999993295729248, 1.0, 1.0, 0.9999992103693118, 0.9999976607241362, 0.999999687183719, 1.0, 1.0, 0.9999851444463449, 1.0, 0.9999988527586582, 0.9999439014415831, 1.0, 0.9996604233691999, 1.0, 1.0, 1.0, 1.0, 1.0, 0.999999687183719]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<span style='color: rgb(179, 3, 38)'><</span><span style='color: rgb(179, 3, 38)'>summary</span><span style='color: rgb(179, 3, 38)'>_of</span><span style='color: rgb(179, 3, 38)'>_patch</span><span style='color: rgb(179, 3, 38)'>_one</span><span style='color: rgb(179, 3, 38)'>>\n",
       "</span><span style='color: rgb(227, 108, 84)'>The</span><span style='color: rgb(189, 210, 246)'> first</span><span style='color: rgb(179, 3, 38)'> patch</span><span style='color: rgb(180, 205, 250)'> introduces</span><span style='color: rgb(141, 175, 253)'> changes</span><span style='color: rgb(242, 145, 115)'> to</span><span style='color: rgb(207, 217, 234)'> the</span><span style='color: rgb(237, 208, 193)'> comparison</span><span style='color: rgb(245, 160, 129)'> and</span><span style='color: rgb(205, 66, 58)'> hashing</span><span style='color: rgb(194, 212, 243)'> methods</span><span style='color: rgb(212, 79, 66)'> of</span><span style='color: rgb(200, 56, 53)'> a</span><span style='color: rgb(244, 196, 173)'> Field</span><span style='color: rgb(193, 42, 48)'> class</span><span style='color: rgb(245, 158, 127)'>.</span><span style='color: rgb(184, 207, 248)'> Specifically</span><span style='color: rgb(237, 132, 103)'>,</span><span style='color: rgb(181, 8, 39)'> it</span><span style='color: rgb(246, 186, 159)'> adds</span><span style='color: rgb(214, 219, 228)'> a</span><span style='color: rgb(236, 130, 102)'> condition</span><span style='color: rgb(238, 134, 105)'> to</span><span style='color: rgb(192, 211, 245)'> the</span><span style='color: rgb(244, 154, 123)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>eq</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(210, 75, 63)'> and</span><span style='color: rgb(179, 3, 38)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>lt</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(185, 22, 42)'> methods</span><span style='color: rgb(187, 26, 43)'> to</span><span style='color: rgb(244, 194, 170)'> check</span><span style='color: rgb(185, 22, 42)'> if</span><span style='color: rgb(231, 117, 92)'> both</span><span style='color: rgb(247, 181, 152)'> the</span><span style='color: rgb(225, 218, 214)'> self</span><span style='color: rgb(181, 8, 39)'> and</span><span style='color: rgb(194, 45, 49)'> other</span><span style='color: rgb(229, 112, 87)'> instances</span><span style='color: rgb(188, 31, 44)'> have</span><span style='color: rgb(194, 45, 49)'> a</span><span style='color: rgb(246, 185, 157)'> '</span><span style='color: rgb(179, 3, 38)'>model</span><span style='color: rgb(179, 3, 38)'>'</span><span style='color: rgb(179, 3, 38)'> attribute</span><span style='color: rgb(243, 198, 176)'> and</span><span style='color: rgb(241, 144, 114)'> if</span><span style='color: rgb(156, 188, 254)'> they</span><span style='color: rgb(230, 114, 89)'> do</span><span style='color: rgb(181, 8, 39)'>,</span><span style='color: rgb(126, 161, 249)'> whether</span><span style='color: rgb(146, 180, 254)'> they</span><span style='color: rgb(244, 157, 126)'> are</span><span style='color: rgb(228, 216, 209)'> different</span><span style='color: rgb(217, 220, 224)'> models</span><span style='color: rgb(243, 198, 176)'>.</span><span style='color: rgb(201, 59, 55)'> If</span><span style='color: rgb(246, 185, 157)'> they</span><span style='color: rgb(179, 3, 38)'> are</span><span style='color: rgb(219, 92, 74)'> different</span><span style='color: rgb(244, 155, 124)'>,</span><span style='color: rgb(184, 17, 41)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>eq</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(214, 82, 67)'> returns</span><span style='color: rgb(205, 66, 58)'> False</span><span style='color: rgb(220, 94, 75)'>,</span><span style='color: rgb(201, 59, 55)'> and</span><span style='color: rgb(179, 3, 38)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>lt</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(246, 171, 141)'> compares</span><span style='color: rgb(211, 77, 64)'> the</span><span style='color: rgb(233, 121, 94)'> models</span><span style='color: rgb(246, 164, 134)'> based</span><span style='color: rgb(179, 3, 38)'> on</span><span style='color: rgb(190, 35, 45)'> their</span><span style='color: rgb(144, 178, 254)'> meta</span><span style='color: rgb(216, 219, 225)'> labels</span><span style='color: rgb(187, 26, 43)'>.</span><span style='color: rgb(245, 193, 168)'> Additionally</span><span style='color: rgb(179, 3, 38)'>,</span><span style='color: rgb(210, 75, 63)'> the</span><span style='color: rgb(240, 141, 111)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>hash</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(179, 3, 38)'> method</span><span style='color: rgb(188, 31, 44)'> is</span><span style='color: rgb(222, 98, 78)'> modified</span><span style='color: rgb(179, 3, 38)'> to</span><span style='color: rgb(243, 152, 121)'> include</span><span style='color: rgb(185, 22, 42)'> the</span><span style='color: rgb(179, 3, 38)'> model</span><span style='color: rgb(181, 8, 39)'>'s</span><span style='color: rgb(181, 8, 39)'> meta</span><span style='color: rgb(179, 3, 38)'> label</span><span style='color: rgb(182, 13, 40)'> in</span><span style='color: rgb(179, 3, 38)'> the</span><span style='color: rgb(179, 3, 38)'> hash</span><span style='color: rgb(226, 106, 83)'> if</span><span style='color: rgb(179, 3, 38)'> the</span><span style='color: rgb(242, 201, 181)'> '</span><span style='color: rgb(179, 3, 38)'>model</span><span style='color: rgb(179, 3, 38)'>'</span><span style='color: rgb(179, 3, 38)'> attribute</span><span style='color: rgb(243, 198, 176)'> is</span><span style='color: rgb(179, 3, 38)'> present</span><span style='color: rgb(207, 217, 234)'>,</span><span style='color: rgb(247, 173, 143)'> otherwise</span><span style='color: rgb(201, 59, 55)'>,</span><span style='color: rgb(179, 3, 38)'> it</span><span style='color: rgb(224, 218, 215)'> falls</span><span style='color: rgb(179, 3, 38)'> back</span><span style='color: rgb(179, 3, 38)'> to</span><span style='color: rgb(223, 100, 79)'> hashing</span><span style='color: rgb(182, 13, 40)'> the</span><span style='color: rgb(196, 48, 50)'> creation</span><span style='color: rgb(240, 204, 185)'>_counter</span><span style='color: rgb(176, 203, 251)'> alone</span><span style='color: rgb(181, 8, 39)'>.\n",
       "</span><span style='color: rgb(179, 3, 38)'></</span><span style='color: rgb(179, 3, 38)'>summary</span><span style='color: rgb(179, 3, 38)'>_of</span><span style='color: rgb(179, 3, 38)'>_patch</span><span style='color: rgb(179, 3, 38)'>_one</span><span style='color: rgb(179, 3, 38)'>>\n",
       "\n",
       "</span><span style='color: rgb(179, 3, 38)'><</span><span style='color: rgb(179, 3, 38)'>summary</span><span style='color: rgb(179, 3, 38)'>_of</span><span style='color: rgb(179, 3, 38)'>_patch</span><span style='color: rgb(179, 3, 38)'>_two</span><span style='color: rgb(179, 3, 38)'>>\n",
       "</span><span style='color: rgb(179, 3, 38)'>The</span><span style='color: rgb(179, 3, 38)'> second</span><span style='color: rgb(179, 3, 38)'> patch</span><span style='color: rgb(238, 134, 105)'> is</span><span style='color: rgb(179, 3, 38)'> identical</span><span style='color: rgb(179, 3, 38)'> to</span><span style='color: rgb(179, 3, 38)'> the</span><span style='color: rgb(179, 3, 38)'> first</span><span style='color: rgb(240, 204, 185)'> patch</span><span style='color: rgb(218, 220, 223)'>,</span><span style='color: rgb(231, 214, 205)'> introducing</span><span style='color: rgb(179, 3, 38)'> the</span><span style='color: rgb(184, 17, 41)'> same</span><span style='color: rgb(168, 197, 253)'> changes</span><span style='color: rgb(201, 59, 55)'> to</span><span style='color: rgb(187, 26, 43)'> the</span><span style='color: rgb(215, 219, 226)'> comparison</span><span style='color: rgb(188, 31, 44)'> and</span><span style='color: rgb(179, 3, 38)'> hashing</span><span style='color: rgb(224, 102, 80)'> methods</span><span style='color: rgb(187, 26, 43)'> of</span><span style='color: rgb(244, 196, 173)'> a</span><span style='color: rgb(179, 3, 38)'> Field</span><span style='color: rgb(179, 3, 38)'> class</span><span style='color: rgb(191, 40, 46)'>.</span><span style='color: rgb(206, 68, 60)'> It</span><span style='color: rgb(178, 203, 251)'> adds</span><span style='color: rgb(245, 192, 167)'> conditions</span><span style='color: rgb(214, 82, 67)'> to</span><span style='color: rgb(187, 209, 247)'> check</span><span style='color: rgb(241, 202, 182)'> for</span><span style='color: rgb(214, 82, 67)'> the</span><span style='color: rgb(246, 189, 164)'> presence</span><span style='color: rgb(246, 170, 140)'> and</span><span style='color: rgb(194, 45, 49)'> equality</span><span style='color: rgb(179, 3, 38)'> of</span><span style='color: rgb(243, 149, 118)'> the</span><span style='color: rgb(181, 8, 39)'> '</span><span style='color: rgb(179, 3, 38)'>model</span><span style='color: rgb(179, 3, 38)'>'</span><span style='color: rgb(181, 8, 39)'> attribute</span><span style='color: rgb(182, 13, 40)'> in</span><span style='color: rgb(234, 125, 97)'> both</span><span style='color: rgb(245, 192, 167)'> the</span><span style='color: rgb(201, 59, 55)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>eq</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(179, 3, 38)'> and</span><span style='color: rgb(179, 3, 38)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>lt</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(182, 13, 40)'> methods</span><span style='color: rgb(217, 220, 224)'>.</span><span style='color: rgb(162, 192, 254)'> If</span><span style='color: rgb(247, 174, 145)'> the</span><span style='color: rgb(226, 106, 83)'> models</span><span style='color: rgb(214, 82, 67)'> are</span><span style='color: rgb(219, 92, 74)'> different</span><span style='color: rgb(181, 8, 39)'>,</span><span style='color: rgb(245, 192, 167)'> it</span><span style='color: rgb(189, 210, 246)'> alters</span><span style='color: rgb(246, 170, 140)'> the</span><span style='color: rgb(236, 210, 196)'> return</span><span style='color: rgb(247, 179, 151)'> values</span><span style='color: rgb(207, 70, 61)'> accordingly</span><span style='color: rgb(187, 26, 43)'>.</span><span style='color: rgb(184, 207, 248)'> The</span><span style='color: rgb(240, 141, 111)'> `</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>hash</span><span style='color: rgb(179, 3, 38)'>__</span><span style='color: rgb(179, 3, 38)'>`</span><span style='color: rgb(181, 8, 39)'> method</span><span style='color: rgb(218, 90, 72)'> is</span><span style='color: rgb(241, 144, 114)'> also</span><span style='color: rgb(222, 219, 218)'> modified</span><span style='color: rgb(232, 119, 93)'> to</span><span style='color: rgb(230, 215, 207)'> hash</span><span style='color: rgb(247, 178, 149)'> a</span><span style='color: rgb(179, 3, 38)'> tuple</span><span style='color: rgb(193, 42, 48)'> of</span><span style='color: rgb(179, 3, 38)'> the</span><span style='color: rgb(179, 3, 38)'> model</span><span style='color: rgb(179, 3, 38)'>'s</span><span style='color: rgb(179, 3, 38)'> meta</span><span style='color: rgb(179, 3, 38)'> label</span><span style='color: rgb(179, 3, 38)'> and</span><span style='color: rgb(241, 202, 182)'> the</span><span style='color: rgb(179, 3, 38)'> creation</span><span style='color: rgb(207, 70, 61)'>_counter</span><span style='color: rgb(218, 90, 72)'> if</span><span style='color: rgb(181, 8, 39)'> the</span><span style='color: rgb(233, 121, 94)'> '</span><span style='color: rgb(179, 3, 38)'>model</span><span style='color: rgb(179, 3, 38)'>'</span><span style='color: rgb(179, 3, 38)'> attribute</span><span style='color: rgb(230, 215, 207)'> exists</span><span style='color: rgb(240, 139, 109)'>,</span><span style='color: rgb(239, 205, 187)'> otherwise</span><span style='color: rgb(211, 219, 230)'>,</span><span style='color: rgb(197, 50, 51)'> it</span><span style='color: rgb(231, 117, 92)'> hashes</span><span style='color: rgb(200, 56, 53)'> the</span><span style='color: rgb(179, 3, 38)'> creation</span><span style='color: rgb(179, 3, 38)'>_counter</span><span style='color: rgb(236, 128, 100)'> alone</span><span style='color: rgb(179, 3, 38)'>.\n",
       "</span><span style='color: rgb(179, 3, 38)'></</span><span style='color: rgb(179, 3, 38)'>summary</span><span style='color: rgb(179, 3, 38)'>_of</span><span style='color: rgb(179, 3, 38)'>_patch</span><span style='color: rgb(179, 3, 38)'>_two</span><span style='color: rgb(179, 3, 38)'>>\n",
       "\n",
       "</span><span style='color: rgb(179, 3, 38)'><</span><span style='color: rgb(179, 3, 38)'>equ</span><span style='color: rgb(179, 3, 38)'>ivalent</span><span style='color: rgb(179, 3, 38)'>_or</span><span style='color: rgb(179, 3, 38)'>_different</span><span style='color: rgb(179, 3, 38)'>>\n",
       "</span><span style='color: rgb(179, 3, 38)'>equ</span><span style='color: rgb(179, 3, 38)'>ivalent</span><span style='color: rgb(179, 3, 38)'>\n",
       "</span><span style='color: rgb(179, 3, 38)'></</span><span style='color: rgb(179, 3, 38)'>equ</span><span style='color: rgb(179, 3, 38)'>ivalent</span><span style='color: rgb(179, 3, 38)'>_or</span><span style='color: rgb(179, 3, 38)'>_different</span><span style='color: rgb(179, 3, 38)'>></span>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of tokens: 282\n"
     ]
    }
   ],
   "source": [
    "import matplotlib\n",
    "\n",
    "colormap = matplotlib.colormaps['coolwarm']  # Get the Viridis colormap\n",
    "\n",
    "def get_color(position):\n",
    "    \"\"\"Helper function to get a color from the coolwarm colormap.\n",
    "\n",
    "    Args:\n",
    "        position: A float between 0.0 and 1.0 representing position along the gradient.\n",
    "\n",
    "    Returns:\n",
    "        A CSS-compatible RGB color string.\n",
    "    \"\"\"\n",
    "    color = colormap(position)  # Get RGBA (A = alpha, ignored)\n",
    "    r, g, b = [int(x * 255) for x in color[:3]]  # Convert to 0-255 range\n",
    "    return f\"rgb({r}, {g}, {b})\"\n",
    "\n",
    "def highlight_text(api_response: ChatCompletion):\n",
    "    tokens = api_response.choices[0].logprobs.content\n",
    "    # show all token probabilities\n",
    "    print([np.exp(token.logprob) for token in tokens])\n",
    "\n",
    "    html_output = \"\"\n",
    "    num_tokens = len(tokens)\n",
    "\n",
    "    for token in tokens:\n",
    "        token_str = bytes(token.bytes).decode(\"utf-8\")\n",
    "        h = np.exp(token.logprob)\n",
    "        # Color based on normalized position\n",
    "        if \"equivalent\" in token_str:\n",
    "            print(h)\n",
    "        color = get_color(h)\n",
    "        # Add colored token to HTML output\n",
    "        html_output += f\"<span style='color: {color}'>{token_str}</span>\" \n",
    "\n",
    "    display(HTML(html_output)) \n",
    "    print(f\"Total number of tokens: {num_tokens}\")\n",
    "highlight_text(response)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "sweepai-hFy5FX7Z-py3.10",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
